/**
 * Project Name:meatball-core
 * File Name:TradePrecreate.java
 * Package Name:com.meatball.utils.alipay
 * Date:2018年3月16日上午11:14:46
 * Copyright (c) ©1994-2018 Scjydz.com All Rights Reserved.
*/
package com.meatball.base.pay.utils;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.meatball.base.pay.order.model.PayOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.meatball.utils.pay.params.AlipayParams;
import com.meatball.utils.pay.properties.AlipayPayProperties;

/**
 * @Title: TradePrecreate.java
 * @Package com.meatball.utils.alipay
 * @Description: TODO(支付宝支付)
 * @author 張翔宇
 * @date 2018年3月16日 上午11:14:46
 * @version V1.0
 */
@Component
public class AlipayTradePrecreate {
	private static final Logger log = LoggerFactory.getLogger(AlipayTradePrecreate.class);
	
	@Resource
	private AlipayPayProperties properties;
	
	/**
	 * @Title: PlaceOrder
	 * @Description: TODO(预下单操作)
	 * @return String 返回类型
	 * @throws AlipayApiException 
	 */
	public AlipayTradePrecreateResponse placeOrder(AlipayParams params) {
		AlipayClient alipayClient = new DefaultAlipayClient(
				properties.getOpenApiDomain(),
				properties.getAppid(),
				properties.getPrivateKey(),
				"json",
				"utf-8",
				properties.getAlipayPublicKey(),
				"RSA2");
		
		// 参数说明请参照支付宝：https://docs.open.alipay.com/api_1/alipay.trade.precreate
		AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
		// 设置回调地址
		request.setNotifyUrl(properties.getNotifyUrl());
		// 组装内容参数
		Map<String, String> orderMap = new HashMap<>();
		// 商户订单号,64个字符以内、只能包含字母、数字、下划线；需保证在商户端不重复
		orderMap.put("out_trade_no", params.getOrderId());
		// 卖家支付宝用户ID。 如果该值为空，则默认为商户签约账号对应的支付宝用户ID
		orderMap.put("seller_id", "");
		// 订单总金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000] 如果同时传入了【打折金额】，
		// 【不可打折金额】，【订单总金额】三者，则必须满足如下条件：【订单总金额】=【打折金额】+【不可打折金额】
		orderMap.put("total_amount", params.getBalance());
		// 可打折金额. 参与优惠计算的金额，单位为元，精确到小数点后两位，取值范围[0.01,100000000] 如果该值未传入，
		// 但传入了【订单总金额】，【不可打折金额】则该值默认为【订单总金额】-【不可打折金额】
		orderMap.put("discountable_amount", "");
		// 订单标题
		orderMap.put("subject", "南充中心医院-一卡通");
		// 支付超时设置为2分钟
		orderMap.put("timeout_express", "2m");
		if(params.getOrderType() == 1) {
			// 禁用信用卡消费
			orderMap.put("disable_pay_channels", "credit_group");
		}
		// 配置明细信息

		log.info("支付宝预下单请求参数：" + JSON.toJSON(orderMap));
		request.setBizContent(JSON.toJSONString(orderMap));
		
		//通过alipayClient调用API，获得对应的response类
		AlipayTradePrecreateResponse response = new AlipayTradePrecreateResponse();
		try {
			response = alipayClient.execute(request);
			 /*String basePath = "d:/Users/meatball/file/";
             String fileName = String.format("alipay%szfb-%s.png", File.separator, response.getOutTradeNo());
             String filePath = new StringBuilder(basePath).append(fileName).toString();
			 ZxingUtils.getQRCodeImge(response.getQrCode(), 256, filePath);*/
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		System.out.print(response.getBody());
		log.info("支付宝预下单返回结果：" + response.getBody());
		return response;
	}
	

	/**
	 * @Title: verifySignature 
	 * @Description: TODO(异步结果验签) 
	 * @param params 参数列表(包括待验签参数和签名值sign) key-参数名称 value-参数值
	 * @return boolean    返回类型
	 */
	public boolean verifySignature(Map<String, String> params) {
		boolean verify = false;
		try {
			verify = AlipaySignature.rsaCheckV1(params, properties.getAlipayPublicKey(), "utf-8", "RSA2");
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		System.out.println(verify);
		return verify;
	}

	/**
	 * h5 支付
	 * @param payOrder
	 * @return
	 */
	public String h5Pay(PayOrder payOrder) {
		// SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
		//调用RSA签名方式
		AlipayClient alipayClient = new DefaultAlipayClient(
				properties.getOpenApiDomain(),
				properties.getAppid(),
				properties.getPrivateKey(),
				"json",
				"utf-8",
				properties.getAlipayPublicKey(),
				"RSA2");
		AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();

		// 封装请求支付信息
		AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
		// 商户订单号，商户网站订单系统中唯一订单号，必填
		model.setOutTradeNo(payOrder.getOutTradeNo());
		// 订单名称，必填
		model.setSubject(payOrder.getOrderName());
		// 付款金额，必填
		String totalAmount = String.valueOf(payOrder.getTotalAmountText());
		model.setTotalAmount(totalAmount);
		// 商品描述，可空
		model.setBody(payOrder.getOrderSource());
		// 超时时间 可空
		model.setTimeoutExpress("2m");
		// 销售产品码 必填
		model.setProductCode("QUICK_WAP_WAY");
		alipay_request.setBizModel(model);

		// 设置异步通知地址
		 alipay_request.setNotifyUrl(properties.getNotifyUrl());
		// 设置同步地址
		alipay_request.setReturnUrl(properties.getReturnUrl());

		// form表单生产, 唤起支付宝支付
		String form = "";
		try {
			// 调用SDK生成表单
			 form = alipayClient.pageExecute(alipay_request).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return form;
	}

	/**
	 * @Title: alipayTradeRefund
	 * @Description: todo(退款)
	 * @Params: [outTradeNo, refundAmount]
	 * @Return void    返回类型
	 * @Author 張翔宇
	 * @Date 2018/5/22 15:54
	 * code : 10000 表示成功
	 * trade_no： 交易流水号
	 * msg：消息
	 * mch_id: 商户订单号
	 */
	public Map<String, String> alipayTradeRefund(String outTradeNo, String tradeNo,  String refundAmount) {
		Map<String, String> result = new HashMap<>();
		AlipayClient alipayClient = new DefaultAlipayClient(
				properties.getOpenApiDomain(),
				properties.getAppid(),
				properties.getPrivateKey(),
				"json",
				"utf-8",
				properties.getAlipayPublicKey(),
				"RSA2");
		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
		// 组装内容参数
		Map<String, String> orderMap = new HashMap<>();
		orderMap.put("out_trade_no", outTradeNo);
		orderMap.put("trade_no", tradeNo);
		orderMap.put("refund_amount", refundAmount);
		orderMap.put("out_request_no", String.valueOf(System.currentTimeMillis()));
		log.info("退款请求参数：" + JSON.toJSONString(orderMap));
		request.setBizContent(JSON.toJSONString(orderMap));

		try {
			AlipayTradeRefundResponse response = alipayClient.execute(request);
			result.put("code", response.getCode());
			result.put("trade_no", response.getTradeNo());
			result.put("msg", response.getSubMsg());
			result.put("mch_id", response.getOutTradeNo());
			log.info("支付宝退款：" + JSON.toJSONString(result));
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return result;
	}
}
